package com.refusea.remoting.alibaba.commons

import com.refusea.commons.http.Https
import com.refusea.commons.utils.Digests
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.Locale


/**
 * @author Zhang Yan, 2023/9/7
 *
 **/
object AlibabaCommonHeaders {

    private const val ACCESS_KEY_ID = "?"
    private val ACCESS_KEY_SECRET = "?".toByteArray()

    /**
     * generate Date header, compute authorization and add to headers
     * @see <a href="https://help.aliyun.com/zh/oss/developer-reference/include-signatures-in-the-authorization-header?spm=a2c4g.11186623.0.i1#concept-aml-vv2-xdb">api</a>
     */
    fun authorization(
        method: Https.Method,
        bucket: String,
        key: String,
        headers: List<Pair<String, Any>> = emptyList(),
    ): List<Pair<String, Any>> {
        val date = date()
        val contentType = headers.firstOrNull { it.first == "Content-Type" }

        val buff = StringBuilder()
        // method
        buff.append(method).append("\n")
        // Content-MD5
        buff.append("\n")
        // ContentType
        if (contentType != null) {
            buff.append(contentType.second)
        }
        buff.append("\n")
        // Date
        buff.append(date).append("\n")

        buff.append("/").append(bucket).append("/").append(key)

        val message = buff.toString()
        val digest = Digests.base64HmacSha1(message, ACCESS_KEY_SECRET)
        return headers + listOf(
            "Date" to date,
            "Authorization" to "OSS $ACCESS_KEY_ID:$digest"
        )
    }

    private val RFC_1123 =
        DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
    private val GMT = ZoneId.of("GMT")

    private fun date(): String {
        return ZonedDateTime.now(GMT).format(RFC_1123)
    }

}
